home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / relmod.arc / relmod.asm < prev   
Assembly Source File  |  1987-08-24  |  12KB  |  409 lines

  1. *
  2. *    New version of relmod.
  3. *    Made by J.A.M.Vermaseren, 17-12-1986.
  4. *    Public domain. This program may be copied for free only.
  5. *    Anybody selling public domain disks with whatever tiny profit
  6. *    beyond the direct costs should send me Dfl 2,-- per copy ( $1 ).
  7. *    My address : J.Vermaseren, Leerdamhof 441, 1108CL Amsterdam.
  8. *    Be fair : If you get something for the trouble I want something
  9. *    for mine.
  10. *
  11. ******************************************************************************
  12. *                                         *
  13. *    Variables in the heap :    ( a6 is heap pointer )                 *
  14. *                                         *
  15. *    0    Number of characters read into input buffer             *
  16. *    4    Output error information from reloc.                 *
  17. *    8    Last relocation address.                     *
  18. *    12    Little trap routine.                         *
  19. *    24    Input name.                             *    
  20. *                                         *
  21. *    Variables in the registers :                         *
  22. *                                         *
  23. *    d7    Input file handle                         *
  24. *    d6    Output file handle                         *
  25. *    d5    (reloc) characters in output buffer                 *
  26. *    d4    (reloc)    characters in input buffer                 *
  27. *    d3    Length of the buffers                         *
  28. *    d2    (reloc)    Distance to start of text                 *
  29. *    a5    Output buffer                             *
  30. *    a4    (reloc) Input buffer                         *
  31. *    a3    (reloc) Next position in output buffer                 *
  32. *    a2    (reloc) Next position in input buffer                 *    
  33. *                                         *
  34. ******************************************************************************
  35. *
  36. *    The startup is done in a particular way, to build the heap before
  37. *    the setblock is done. The Atari ROM refuses to execute trap functions
  38. *    and return to the ROM safely. This way a little routine like
  39. *        move.l    (sp)+,offset+8(a6)
  40. *        trap    #1
  41. *        jmp    unimportant
  42. *    can be put at offset(a6) and all trap #1 replaced by jmp offset(a6).
  43. *    In this program offset is 12, so jmp 12(a6) is equivalent to trap #1
  44. *    This has to be done before the first trap call, ie the setblock.
  45. *
  46. start:    move.l    4(sp),a3        * Base page address.
  47.     move.l    12(a3),d0        * Length of text.
  48.     add.l    20(a3),d0        * Initialized data.
  49.     add.l    28(a3),d0        * Uninitialized data.
  50.     add.l    #$100,d0        * + 100 bytes basepage.
  51.     lea    (a3,d0.l),a6        * Heap pointer.
  52.     add.l    #$200,d0        * Heap + stack space.
  53.     move.l    sp,d3            * Top of available memory.
  54.     lea    (a3,d0.l),sp        * Install new stack pointer
  55.     sub.l    sp,d3            * Available for copying.
  56.     andi.l    #$FFFFF800,d3        * Make multiple of 2048.
  57.     beq    nomemory        * Not enough memory.
  58.     add.l    d3,d0            * Total memory requirement.
  59.     lsr.l    #1,d3            * Space for each buffer.
  60.     move.l    sp,-(sp)        * Input buffer for later.
  61.     lea    (sp,d3.l),a5        * Output buffer.
  62. *
  63. *    Just for fun. I don't expect you to put it in the ROM cartridge.
  64. *
  65.     move.l    #$2D5F0014,12(a6)    * move.l (sp)+,20(a6)
  66.     move.l    #$4E414EF9,16(a6)    * trap     #1
  67. *                    * jmp     .....
  68. *
  69.     move.l    d0,-(sp)        * Total reservation.
  70.     move.l    a3,-(sp)        * Start address.
  71.     clr.w    -(sp)            * For GEMDOS. It eats its stack!!!!!!
  72.     move.w    #$4A,-(sp)        * Setblock.
  73.     jsr    12(a6)            * This is trap #1
  74.     lea    12(sp),sp        * Reset the stack.
  75.     tst.l    d0
  76.     bne    nomemory
  77. *
  78. *    Study the command tail. Problem : What if there ain't any.
  79. *    Normally : Pascal string : One byte with the length of the rest, and
  80. *                   then the rest.
  81. *    Is none     : 60,1A or something. So if 60, then look at offset 18. If
  82. *           no tail there is a zero there. With tail there ain't.
  83. *
  84.     lea    $80(a3),a4        * The beginning of the command tail
  85.     moveq.l    #0,d5
  86.     move.b    (a4)+,d5        * String length. String at a4.
  87.     beq    notail            * Length 0.
  88.     cmpi.w    #$60,d5
  89.     bne    istail            * There is a command tail.
  90.     tst.b    17(a4)
  91.     beq    notail            * No commmand tail --> error message.
  92. istail:    lea    (a4,d5.w),a3        * First address beyond the tail.
  93.     moveq.l    #0,d0
  94.     moveq.l    #$20,d2            * This is a blank.
  95. loop1:    move.b    (a4)+,d0        * Get one character.
  96.     cmp.b    d2,d0
  97.     beq    loop1            * Strip leading blanks.
  98.     cmpi.b    #$2D,d0
  99.     bne    nodash
  100.     move.b    (a4)+,d0        * Skip a dash.
  101. nodash:    cmp.l    a4,a3            * Do we have a nontrivial character ?
  102.     blt    notail
  103.     lea    24(a6),a0        * For storage.
  104.     move.l    a0,a1            * For later to find the extention.
  105.     move.l    a0,a2            * Keep track of the '.'
  106. loop2:    cmp.b    #$2E,d0
  107.     bne    loop2a
  108.     move.l    a0,a2            * Address of the last period
  109. loop2a:    move.b    d0,(a0)+
  110.     move.b    (a4)+,d0
  111.     cmp.b    d2,d0            * Go till blank or end of tail
  112.     beq    endpar
  113.     cmp.l    a4,a3
  114.     bge    loop2            * A good character --> copy.
  115. endpar:
  116.     cmp.l    a2,a1            * Was there a period ?
  117.     bne    fullnm            * Got a full name.
  118.     move.l    a0,a2
  119.     move.b    #$2E,(a0)+        * '.'
  120.     move.b    #$36,(a0)+        * '6'
  121.     move.b    #$38,(a0)+        * '8'
  122.     move.b    #$4B,(a0)+        * 'K'
  123. fullnm:    clr.b    (a0)
  124.     clr.w    -(sp)            * Reading this file only.
  125.     move.l    a1,-(sp)        * Address of the file name.
  126.     move.w    #$3D,-(sp)        * Fopen.
  127.     jsr    12(a6)            * This is trap #1
  128.     addq.l    #8,sp
  129.     tst.l    d0            * Did the file get opened?
  130.     bmi    filerr
  131.     move.l    d0,d7            * Store the handle.
  132. *
  133.     moveq.l    #0,d0
  134. loop3:    move.b    (a4)+,d0
  135.     cmp.b    d2,d0
  136.     beq    loop3
  137.     cmp.l    a4,a3
  138.     bmi    only1            * Only one parameter --> transform.
  139.     lea    -1(a4),a1        * Start of second name.
  140. loop4:    move.b    (a4)+,d0
  141.     cmp.b    d2,d0
  142.     beq    param2
  143.     cmp.l    a4,a3
  144.     bge    loop4
  145.     bra    param2
  146. only1:    lea    1(a2),a4
  147.     move.b    #$50,(a4)+
  148.     move.b    #$52,(a4)+
  149.     move.b    #$47,(a4)+
  150.     addq.l    #1,a4
  151. param2:    subq.l    #1,a4
  152.     move.b    (a4),d4            * Save old character
  153.     clr.b    (a4)            * End on 0 for GEMDOS.
  154.     clr.w    -(sp)            * Read and write.
  155.     move.l    a1,-(sp)
  156.     move.w    #$3C,-(sp)        * Fcreate
  157.     jsr    12(a6)            * This is trap #1
  158.     addq.l    #8,sp
  159.     move.b    d4,(a4)            * Restore old character.
  160.     tst.l    d0
  161.     bmi    filer2
  162.     move.l    d0,d6            * Save the output handle.
  163. *
  164. *    Now we have two opened files and the buffers are ready.
  165. *
  166.           move.l    (sp)+,a4        * Input buffer.
  167.     bsr    reloc            * Make the relocation table.
  168.     move.w    d6,-(sp)        * Output file.
  169.     bsr    fclose
  170.     move.w    d7,(sp)            * Input file.
  171.     bsr    fclose
  172.     addq.l    #2,sp
  173.     move.w    4(a6),-(sp)        * Error code from reloc ( or none ).
  174.     move.w    #$4C,-(sp)        * Pterm: exit with possible error code.
  175.     jsr    12(a6)            * This is trap #1
  176. *
  177. *    Error messages when a file cannot be opened.
  178. *
  179. filer2:    move.w    d7,-(sp)
  180.     bsr    fclose            * First close the input file.
  181.     addq.l    #2,sp
  182. *
  183. filerr:    pea    nofil(pc)        * First part of error message.
  184.     bsr    out_str
  185.     addq.l    #4,sp
  186.     move.l    a1,-(sp)        * Pointer to the name of the file.
  187. conti:    bsr    out_str
  188.     addq.l    #4,sp
  189.     pea    newlin(pc)        * CR+linefeed.
  190.     bsr    out_str
  191.     addq.l    #4,sp
  192.     bra    errext
  193. *
  194. nomemory:
  195.     pea    nomem(pc)        * Shortage of memory.
  196.     bra    conti
  197. *
  198. notail:    pea    use(pc)            * Show correct usage.
  199.     bsr    out_str
  200.     addq.l    #4,sp
  201. errext:
  202.     move.w    #-1,-(sp)
  203.     move.w    #$4C,-(sp)
  204.     jsr    12(a6)            * Pterm with errorflag.
  205. *
  206. use:    dc.b    'Usage: FASTREL [-]file[.68K] [output file]'
  207. newlin:    dc.b    $0D,$0A,0,0
  208. nofil:    dc.b    'Cannot open file ',0
  209. nomem:    dc.b    'Not enough memory available.',0,0
  210. errrel:    dc.b    'File error.',0
  211. *
  212. *    Close a file
  213. *
  214. fclose:    move.w    4(sp),-(sp)
  215.     move.w    #$3E,-(sp)        * Fclose
  216.     jsr    12(a6)            * This is trap #1
  217.     addq.l    #4,sp
  218.     rts
  219. *
  220. *    Routine to write a zero terminated string to the screen.
  221. *
  222. out_str:
  223.     move.l    4(sp),-(sp)
  224.     move.w    #9,-(sp)
  225.     jsr    12(a6)            * This is trap #1
  226.     addq.l    #6,sp
  227.     rts
  228. *
  229. *    The routine to make a relocation table.
  230. *
  231. reloc:    bsr    readin            * Read the first buffer.
  232.     bmi    error
  233.     moveq.l    #28,d4            * Header length.
  234.     add.l    2(a4),d4        * Text length.
  235.     add.l    6(a4),d4        * Data segment.
  236.     add.l    14(a4),d4        * Symbol table.
  237.     bsr    copyd4            * Copy this piece to the output buffer.
  238.     bmi    error
  239.     clr.l    8(a6)            * Start of relocation
  240.     moveq.l    #-4,d2            * Running counter.
  241. rloop:    addq.l    #2,d2
  242. rloopp:    addq.l    #2,d2
  243.     bsr    getone            * Get a single relocation number in d1.
  244.     bne    relend
  245.     andi.w    #7,d1
  246.     cmpi.w    #5,d1
  247.     bne    rloopp            * Not relevant on the ST.
  248.     bsr    getone            * Upper half of a long word. Get next.
  249.     bne    relend            * Originally:
  250.     subq.w    #1,d1            * 1 relative to data segment
  251.     andi.w    #7,d1            * 2 relative to text segment
  252.     cmp.w    #3,d1            * 3 relative to bss
  253.     bge    rloop            * On the ST its all relative to text.
  254. relo1:    tst.l    8(a6)            * First relocation?
  255.     bne    relo2            * No
  256.     move.l    d2,8(a6)
  257.     move.l    d2,d1
  258.     rol.l    #8,d1            * Put now the 4 bytes of d1.
  259.     bsr    putone
  260.     bne    error
  261.     rol.l    #8,d1
  262.     bsr    putone
  263.     bne    error
  264.     rol.l    #8,d1
  265.     bsr    putone
  266.     bne    error
  267.     rol.l    #8,d1
  268.     bsr    putone
  269.     beq    rloop
  270.     bra    error
  271. relo2:    move.l    d2,d1
  272.     sub.l    8(a6),d1        * Difference with the previous one.
  273.     move.l    d2,8(a6)        * The new 'previous one'
  274.     bra    relo4
  275. relo3:    move.l    d1,d2            * If > 254 --> write a 1
  276.     sub.l    #254,d2            * and subtract 254.
  277.     moveq.l    #1,d1
  278.     bsr    putone
  279.     bne    error
  280.     move.l    d2,d1
  281.     move.l    8(a6),d2        * We needed register d2 for scratch.
  282. relo